Don't do completion in the middle of an incomplete hostname
authorFederico Mena Quintero <federico@novell.com>
Wed, 21 Jan 2009 03:17:01 +0000 (03:17 +0000)
committerFederico Mena Quintero <federico@src.gnome.org>
Wed, 21 Jan 2009 03:17:01 +0000 (03:17 +0000)
Fix completion so it doesn't pop up for every character in a URI
hostname:

* gtk/gtkfilechooser.h (GtkFileChooserError): Add a
GTK_FILE_CHOOSER_ERROR_INCOMPLETE_HOSTNAME.

* gtk/gtkfilesystem.c (_gtk_file_system_parse): Return an
"incomplete hostname" error if the user has not typed a full
hostname yet in an URI.

* gtk/gtkfilechooserentry.c (append_common_prefix): If we get an
incomplete hostname, just don't pop up an error, since that is a
transient state and the user doesn't need to be notified about it.
(refresh_current_folder_and_file_part): Don't revert to showing
the base folder if we have an incomplete hostname.
(reload_current_folder): Handle the passed folder being NULL, even
if we must force a reload.  Also, reload the folder if we didn't
have a cancellable for it (i.e. we hadn't started to load it
before).

Signed-off-by: Federico Mena Quintero <federico@novell.com>
svn path=/trunk/; revision=22157

ChangeLog
gtk/gtkfilechooser.h
gtk/gtkfilechooserentry.c
gtk/gtkfilesystem.c

index 8c91c4508c25f3d319e86f1476a1ccf2a2968f4d..bd748794dd2ade7191befd927ca0dda16263bdd3 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
        * gtk/gtkfilechooserdefault.c (set_local_only): Set the local_only
        property on the entry.
 
+       Fix completion so it doesn't pop up for every character in a URI
+       hostname:
+
+       * gtk/gtkfilechooser.h (GtkFileChooserError): Add a
+       GTK_FILE_CHOOSER_ERROR_INCOMPLETE_HOSTNAME.
+
+       * gtk/gtkfilesystem.c (_gtk_file_system_parse): Return an
+       "incomplete hostname" error if the user has not typed a full
+       hostname yet in an URI.
+
+       * gtk/gtkfilechooserentry.c (append_common_prefix): If we get an
+       incomplete hostname, just don't pop up an error, since that is a
+       transient state and the user doesn't need to be notified about it.
+       (refresh_current_folder_and_file_part): Don't revert to showing
+       the base folder if we have an incomplete hostname.
+       (reload_current_folder): Handle the passed folder being NULL, even
+       if we must force a reload.  Also, reload the folder if we didn't
+       have a cancellable for it (i.e. we hadn't started to load it
+       before).
+
 2009-01-20  Matthias Clasen  <mclasen@redhat.com>
 
        * gtk/gtk.symbols:
index e085a7992da70542d8be567d55afcc938c76d0d1..b7983a9660c7b21889c0785bda1e617deb3cc5e9 100644 (file)
@@ -60,7 +60,8 @@ GType gtk_file_chooser_get_type (void) G_GNUC_CONST;
 typedef enum {
   GTK_FILE_CHOOSER_ERROR_NONEXISTENT,
   GTK_FILE_CHOOSER_ERROR_BAD_FILENAME,
-  GTK_FILE_CHOOSER_ERROR_ALREADY_EXISTS
+  GTK_FILE_CHOOSER_ERROR_ALREADY_EXISTS,
+  GTK_FILE_CHOOSER_ERROR_INCOMPLETE_HOSTNAME
 } GtkFileChooserError;
 
 GQuark gtk_file_chooser_error_quark (void);
index c25de12c7b555dee97c730069acde30f44361c63..149d74c45b8259fe789fa77af3a2cbe7bf8a3578 100644 (file)
@@ -661,7 +661,12 @@ append_common_prefix (GtkFileChooserEntry *chooser_entry,
   error = NULL;
   if (!find_common_prefix (chooser_entry, &common_prefix, &unique_file, &is_complete_not_unique, &prefix_expands_the_file_part, &error))
     {
-      if (show_errors)
+      /* If the user types an incomplete hostname ("http://foo" without a slash
+       * after that), it's not an error.  We just don't want to pop up a
+       * meaningless completion window in that state.
+       */
+      if (!g_error_matches (error, GTK_FILE_CHOOSER_ERROR, GTK_FILE_CHOOSER_ERROR_INCOMPLETE_HOSTNAME)
+         && show_errors)
        {
          beep (chooser_entry);
          pop_up_completion_feedback (chooser_entry, _("Invalid path"));
@@ -1403,7 +1408,8 @@ reload_current_folder (GtkFileChooserEntry *chooser_entry,
 
   if (chooser_entry->current_folder_file)
     {
-      if ((folder_file && !g_file_equal (folder_file, chooser_entry->current_folder_file))
+      if ((folder_file && !(g_file_equal (folder_file, chooser_entry->current_folder_file)
+                           && chooser_entry->load_folder_cancellable))
          || force_reload)
        {
          reload = TRUE;
@@ -1419,7 +1425,7 @@ reload_current_folder (GtkFileChooserEntry *chooser_entry,
 
           discard_current_folder (chooser_entry);
          g_object_unref (chooser_entry->current_folder_file);
-         chooser_entry->current_folder_file = g_object_ref (folder_file);
+         chooser_entry->current_folder_file = (folder_file) ? g_object_ref (folder_file) : NULL;
        }
     }
   else
@@ -1443,6 +1449,7 @@ refresh_current_folder_and_file_part (GtkFileChooserEntry *chooser_entry,
   gchar *file_part;
   gsize total_len, file_part_len;
   gint file_part_pos;
+  GError *error;
 
   editable = GTK_EDITABLE (chooser_entry);
 
@@ -1462,14 +1469,22 @@ refresh_current_folder_and_file_part (GtkFileChooserEntry *chooser_entry,
     }
 
   text = gtk_editable_get_chars (editable, 0, end_pos);
-  
+
+  error = NULL;
   if (!chooser_entry->file_system ||
       !chooser_entry->base_folder ||
       !_gtk_file_system_parse (chooser_entry->file_system,
                               chooser_entry->base_folder, text,
-                              &folder_file, &file_part, NULL)) /* NULL-GError */
+                              &folder_file, &file_part, &error))
     {
-      folder_file = (chooser_entry->base_folder) ? g_object_ref (chooser_entry->base_folder) : NULL;
+      if (g_error_matches (error, GTK_FILE_CHOOSER_ERROR, GTK_FILE_CHOOSER_ERROR_INCOMPLETE_HOSTNAME))
+       folder_file = NULL;
+      else
+       folder_file = (chooser_entry->base_folder) ? g_object_ref (chooser_entry->base_folder) : NULL;
+
+      if (error)
+       g_error_free (error);
+
       file_part = g_strdup ("");
       file_part_pos = -1;
     }
index 46c36cb05390995322fa5aad2b21cb5f448f7404..bc6cbf588db2ce8ad2658c4e05a715b56583556f 100644 (file)
@@ -672,6 +672,7 @@ _gtk_file_system_parse (GtkFileSystem     *file_system,
   gboolean result = FALSE;
   gboolean is_dir = FALSE;
   gchar *last_slash = NULL;
+  gboolean is_uri;
 
   DEBUG ("parse");
 
@@ -680,7 +681,37 @@ _gtk_file_system_parse (GtkFileSystem     *file_system,
 
   last_slash = strrchr (str, G_DIR_SEPARATOR);
 
-  if (str[0] == '~' || g_path_is_absolute (str) || has_uri_scheme (str))
+  is_uri = has_uri_scheme (str);
+
+  if (is_uri)
+    {
+      const char *colon;
+      const char *slash_after_hostname;
+
+      colon = strchr (str, ':');
+      g_assert (colon != NULL);
+      g_assert (strncmp (colon, "://", 3) == 0);
+
+      slash_after_hostname = strchr (colon + 3, '/');
+
+      if (slash_after_hostname == NULL)
+       {
+         /* We don't have a full hostname yet.  So, don't switch the folder
+          * until we have seen a full hostname.  Otherwise, completion will
+          * happen for every character the user types for the hostname.
+          */
+
+         *folder = NULL;
+         *file_part = NULL;
+         g_set_error (error,
+                      GTK_FILE_CHOOSER_ERROR,
+                      GTK_FILE_CHOOSER_ERROR_INCOMPLETE_HOSTNAME,
+                      "Incomplete hostname");
+         return FALSE;
+       }
+    }
+
+  if (str[0] == '~' || g_path_is_absolute (str) || is_uri)
     file = g_file_parse_name (str);
   else
     file = g_file_resolve_relative_path (base_file, str);